﻿using System;
using System.Collections;
using Gp.Scripts.Core;
using UnityEngine;

namespace Gp.Scripts.Core {
    public class AttackGestureSequence : UnitEventGestureSequence {
        private const float BackDistance = 0.1f;
        private const float F1 = .1f;
        private const float F2 = .05f;
        private const float F3 = .25f;


        public BaseUnit CurAttackingTarget { get; private set; } = null;


        private bool _moveTrigger = false;
        private bool _moveBackTrigger = false;
        private Action _onHit;

        public AttackGestureSequence(BaseUnit attackTarget, Action onHitCallBack) {
            _onHit = onHitCallBack;
            
            CurAttackingTarget = attackTarget;
        }


        protected override void OnInit() {
            this.EventListen(UnitAnimEventType.AttackHitEvent, () => HasAnimationHitTriggered = true);
            this.EventListen(UnitAnimEventType.AttackMoveStartEvent, Animation_MoveStart);

            _moveBackTrigger = false;
            _moveTrigger = false;
        }


        /// <summary>
        /// 攻击命中触发函数。在发起攻击并命中后调用，以保证受击相关逻辑正常执行。
        /// </summary>
        private void Animation_OnHit() {
            _onHit?.Invoke();
            _onHit = null;
            CurAttackingTarget = null;
        }

        private void Animation_MoveStart() {
            _moveTrigger = true;
        }

        public override IEnumerator PlayGestureSequence() {
            Animator.Play(UnitAnimatorStateId.PlayingState);

            SetModelStatus(UnitModelStatus.Execute);
            _moveTrigger = false;


            // FeedBackPlayer.PlayAbilityStartFx(UnitReference);
            var targetPos = GetTargetPos();
            UnitReference.Model.ForwardToTarget(targetPos);

            // todo: 将此部分逻辑更该至数据层
            // =========================== 测试用 ===========================================
            // var reaction = new AttackPreReaction(UnitReference,
            //     CurAttackingTarget, UnitReference.ComEquip.CurWeapon);
            // yield return Helpers.BattleLogic.CallReaction(reaction);
            
            while (!HasAnimationHitTriggered) {
                yield return null;
            }

            // if (reaction.CallBack == null)
                // Animation_OnHit();
            // else {
                // yield return reaction.OnCallBack();
                _onHit = null;
                CurAttackingTarget = null;
            // }
        }


        /// <summary>
        /// 判断是否已经触发过攻击命中。
        /// </summary>
        private bool HasAnimationHitTriggered { get; set; }


        private Vector3 GetTargetPos() {
            var position = CurAttackingTarget.transform.position;
            var dir = (UnitReference.transform.position - position).normalized;
            var targetRadius = GetRadius(CurAttackingTarget.Model);
            var selfRadius = GetRadius(Model);

            return position + dir * (targetRadius + selfRadius);
        }

        private float GetRadius(UnitModel model) {
            return model.TryGetComponent<CapsuleCollider>(out var col) ? col.radius : 0.5f;
        }
    }
}